#ifndef INC_COMMANDFACTORY_H
#define INC_COMMANDFACTORY_H

#include <map>
#include <vector>
#include <string>
using std::map;
using std::vector;
using std::string;

#include "command.h"
using Commands::Command;
using Commands::CommandCreator;
using Commands::NotImplemented;

#include <Poco/Net/Socket.h>
using Poco::Net::Socket;

namespace Commands
{

	class CommandFactory
	{
		public:
			/**
			 * Instantiates a CommandFactory with no registered commands
			 */
			CommandFactory();

			/**
			 * Instantiates a CommandFactory and registers the given commands
			 */
			CommandFactory(const vector<Command*>&);

			/**
			 * Copy constructor
			 */
			CommandFactory(const CommandFactory&);

			/**
			 * Constructs a command given a representational string. Throws NotImplemented if the supplied command is not registered. Can also throw exceptions relating to parsing.
			 * @return the command represented by the representational string
			 */
			Command* makeCommand(const string& repr, void* socket);
			
			/**
			 * Registers a Command. If the command already exists, it is registered again.
			 */
			void registerCommand(Command* cmd);

			/**
			 * Unregisters a Command. If the command does not exist, nothing happens.
			 */
			void unregisterCommand(Command* cmd);

			static bool isCommand( const string& string);
		private:
			map<string, CommandCreator> _register;
	};
}
#endif
